package com.saydc.dao;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;

import com.saydc.exceptions.UnableToDeleteException;
import com.saydc.model.Puesto;
import com.saydc.model.PuestoEspecifico;
import com.saydc.model.PuestoTrabajado;
import com.saydc.utils.HibernateUtils;

public class PuestosDAO {
	
	private static PuestosDAO instance;

	public static PuestosDAO getInstance(){
		if(instance == null){
			instance = new PuestosDAO();
		}
		return instance;
	}
	
	@SuppressWarnings("unchecked")
	public ArrayList<Puesto> getPuestosGenericos(){
		ArrayList<Puesto> listaPuestos = new ArrayList<Puesto>();
		Session session = HibernateUtils.currentSession();
		listaPuestos.addAll((List<Puesto>)session.createCriteria(Puesto.class).add(Restrictions.eq("descGenerica", 'G')).list());
		//HibernateUtils.closeSession();
		return listaPuestos;
	}
	
	@SuppressWarnings("unchecked")
	public ArrayList<Puesto> getPuestosEspecificos(){
		ArrayList<Puesto> listaPuestos = new ArrayList<Puesto>();
		Session session = HibernateUtils.currentSession();
		listaPuestos.addAll((List<Puesto>)session.createQuery("select pe from PuestoEspecifico pe").list());
		//HibernateUtils.closeSession();
		return listaPuestos;
	}
	
	public void guardarPuesto(Puesto puesto){
		Session session;
		Transaction tx = null;
		try{
			session = HibernateUtils.currentSession();
			tx = session.beginTransaction();
			session.saveOrUpdate(puesto);
			tx.commit();
		}catch(Exception e){
			tx.rollback();
			e.printStackTrace();
			System.out.println("Error al borrar en la base");
		}finally{
			HibernateUtils.closeSession();
		}
	}
	
	public void borrarPuesto(Puesto puesto) throws UnableToDeleteException{
		Session session;
		Transaction tx = null;
		try{
			session = HibernateUtils.currentSession();
			tx = session.beginTransaction();
			session.delete(puesto);
			tx.commit();
		}catch(Exception e){
			tx.rollback();
			e.printStackTrace();
			System.out.println("Error al borrar en la base [eliminar puesto generico]");
			throw new UnableToDeleteException("El objeto se encuentra referenciado");
		}finally{
			HibernateUtils.closeSession();
		}
	}
	
	public void actualizarPuesto(Puesto puesto){
		Session session;
		Transaction tx = null;
		try{
			session = HibernateUtils.currentSession();
			tx = session.beginTransaction();
			session.update(puesto);
			tx.commit();
		}catch(Exception e){
			tx.rollback();
			e.printStackTrace();
			System.out.println("Error al borrar en la base");
		}finally{
			HibernateUtils.closeSession();
		}
	}
	
	public Puesto getPuesto(int idPuesto){
		Session session = HibernateUtils.currentSession();
		Puesto puesto = (Puesto)session.load(Puesto.class, idPuesto);
		//Puesto puesto = this.getPuestoCriteria(session, idPuesto);
		Hibernate.initialize(puesto);
		puesto.getCaracRequeridas().size();
		//Hibernate.initialize(puesto.getCaracRequeridas());
		HibernateUtils.closeSession();
		return puesto;
	}
	
	public PuestoEspecifico getPuestoEspecifico(int idPuesto){
		Session session = HibernateUtils.currentSession();
		PuestoEspecifico puesto = (PuestoEspecifico)session.load(PuestoEspecifico.class, idPuesto);
		//PuestoEspecifico puesto = this.getPuestoEspecificoCriteria(session, idPuesto);
		Hibernate.initialize(puesto);
		puesto.getCaracRequeridas().size();
		//Hibernate.initialize(puesto.getCaracRequeridas());
		HibernateUtils.closeSession();
		return puesto;
	}
	
	public PuestoEspecifico getPuestoEspecifico(Session session, int idPuesto){
		PuestoEspecifico puesto = (PuestoEspecifico)session.load(PuestoEspecifico.class, idPuesto);
		//PuestoEspecifico puesto =  this.getPuestoEspecificoCriteria(session, idPuesto);
		Hibernate.initialize(puesto.getCaracRequeridas());
		return puesto;
	}

	public PuestoEspecifico getPuestoEspecificoFromLista(List<PuestoEspecifico> listaPuestos, int idPuesto) {
		PuestoEspecifico puestoBuscado = null;
		for(PuestoEspecifico puesto : listaPuestos){
			if(puesto.getIdPuesto() == idPuesto){
				puestoBuscado = puesto;
			}
		}
		return puestoBuscado;
	}

	public Puesto getPuesto(String nombrePuesto) {
		Session session = HibernateUtils.currentSession();
		Puesto puesto = (Puesto)session.createCriteria(Puesto.class).add(Restrictions.eq("nombrePuesto", nombrePuesto)).uniqueResult();
		Hibernate.initialize(puesto);
		HibernateUtils.closeSession();
		return puesto;
	}

	public void guardarPuestoTrabajado(PuestoTrabajado puesto) {
		Session session;
		Transaction tx = null;
		try{
			session = HibernateUtils.currentSession();
			tx = session.beginTransaction();
			session.save(puesto);
			tx.commit();
		}catch(Exception e){
			tx.rollback();
			e.printStackTrace();
			//TODO throw new InsertException("Error al insertar en la base de datos", e.printStackTrace());
			System.out.println("Error al insertar en la base");
		}//TODO ver el lazy de emp
	}
	
	private PuestoEspecifico getPuestoEspecificoCriteria(Session session, int idPuesto) {
		return (PuestoEspecifico)session.createCriteria(PuestoEspecifico.class).add(Restrictions.eq("idPuesto", idPuesto)).uniqueResult();
	}


	private Puesto getPuestoCriteria(Session session, int idPuesto) {
		return (Puesto)session.createCriteria(Puesto.class).add(Restrictions.eq("idPuesto", idPuesto)).uniqueResult();
	}
}
